package com.ete.service.service.log

import android.content.Context
import android.util.Log
import androidx.annotation.StringRes
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.SDCardUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.ToastUtils
import com.blankj.utilcode.util.Utils
import com.ete.service.callback.log.IZipCallback
import com.ete.service.dialog.CommonDialog
import com.ete.service.dialog.MiniLoadingDialog
import com.ete.service.dialog.log.ChooseUploadDirDialog
import com.ete.service.dialog.log.InputDescriptionDialog
import com.ete.service.entry.dialog.CommonDialogEntry
import com.ete.service.entry.log.AppLogEntry
import com.ete.service.manager.ManagerConstant
import com.ete.service.manager.log.LogManager
import com.ete.service.net.api.ServiceApi
import com.ete.service.net.bean.BaseResponse
import com.ete.service.net.exception.ExceptionTranslate
import com.ete.service.net.http.RetrofitClient
import com.ete.service.net.http.param.ParamHelper
import com.ete.service.net.progress.IProgressListener
import com.ete.service.service.R
import com.ete.service.util.ServiceUtil
import com.ete.service.util.SystemLogUtil
import com.ete.service.util.log.EteLog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.File

/**
 * Author:LiXian
 * <p>
 * Desc:上报App日志工具类
 * Version:1.0
 * date 2024/1/8 17:39
 */
object UploadLogUtil {

    private lateinit var mZipEntry: AppLogEntry

    /**
     * 输入内容、压缩进度、上报进度、是否取消压缩
     */
    private var mInputContent: String = ""
    private var mZipProgress: Int = 0
    private var mUploadProgress: Int = 0
    private var isZipCancel: Boolean = false

    private var mUploadLogCall: Call<BaseResponse<Boolean>>? = null

    /**
     * 普通日志
     */
    private val mZipNormalLogDir by lazy {
        SDCardUtils.getSDCardPathByEnvironment() + File.separator +
                "Download" + File.separator + AppUtils.getAppName() +
                File.separator + "normal"
    }

    /**
     * 系统日志
     */
    private val mZipSystemLogDir by lazy {
        SDCardUtils.getSDCardPathByEnvironment() + File.separator +
                "Download" + File.separator + AppUtils.getAppName() +
                File.separator + "system"
    }

    private var mLogDelayJob: Job? = null
    private const val LOG_DELAY_TIME = 5 * 1000L

    /**
     * 上传进度Key
     */
    private var mProgressKey: String? = null

    @JvmStatic
    fun init(zipEntry: AppLogEntry) {
        mZipEntry = zipEntry
        doWithDir()
        cancelLogTask()
        cancelLogDelayJob()
    }

    /**
     * 处理文件目录
     *
     * 注：传入的文件目录地址移除最后“/”
     */
    @JvmStatic
    private fun doWithDir() {
        mZipEntry.mAppDirs = mZipEntry.mAppDirs.map {
            if (it.endsWith(File.separator)) {
                it.removeRange(it.length - 1, it.length)
            } else {
                it
            }
        }.toMutableList()
        mZipEntry.mDefaultUploadDirs = mZipEntry.mDefaultUploadDirs.map {
            if (it.endsWith(File.separator)) {
                it.removeRange(it.length - 1, it.length)
            } else {
                it
            }
        }.toMutableList()
    }

    /**
     * 取消日志任务
     *
     * 注：有可能上次请求没有完成
     */
    @JvmStatic
    fun cancelLogTask() {
        EteLog.d(LogManager.TAG, "取消日志任务")
        mUploadProgress = 0
        mZipProgress = 0
        ZipFileUtil.cancelTask()
        mUploadLogCall?.cancel()
        mUploadLogCall = null
        isZipCancel = true
    }

    /**
     * 获取主题色
     */
    @JvmStatic
    fun getThemeColor(): Int {
        return mZipEntry.mAppThemeColor
    }

    /**
     * 删除压缩文件
     *
     * @param isToastDelete 是否删除提醒
     */
    @JvmStatic
    fun deleteAppZipLogFile(isToastDelete: Boolean = false) {
        FileUtils.deleteFilesInDir(mZipNormalLogDir)
        if (isToastDelete) {
            ToastUtils.showShort(R.string.upload_log_delete_log_success)
        } else {
            EteLog.d(LogManager.TAG, "路径：${mZipNormalLogDir}，删除缓存Log日志")
        }
    }

    /**
     * 是否有压缩包
     */
    @JvmStatic
    fun isHadAppZipLogFile(): Boolean {
        return getAppZipLogFile() != null
    }

    /**
     * 获取日志压缩包
     */
    @JvmStatic
    fun getAppZipLogFile(): File? {
        val isDir = FileUtils.isDir(mZipNormalLogDir)
        if (!isDir) return null
        val mFiles = File(mZipNormalLogDir).listFiles()
        if (mFiles.isNullOrEmpty()) return null
        return mFiles.find {
            FileUtils.getFileExtension(it) == ManagerConstant.ZIP_FILE_EXTENSION
        }
    }

    @JvmStatic
    fun getString(@StringRes res: Int): String {
        return Utils.getApp().getString(res)
    }

    /**
     * 硬件日志文件上传
     *
     * @param isChooseDir 是否选择目录上传
     */
    @JvmStatic
    fun uploadAppLogFile(isChooseDir: Boolean) {
        val mContext = ActivityUtils.getTopActivity() ?: return
        cancelLogTask()
        cancelLogDelayJob()
        val mMiniDialog = MiniLoadingDialog.getMiniDialog(mContext, R.string.upload_check_network)
        mMiniDialog.show()
        CoroutineScope(Dispatchers.IO).launch {
            val mType = NetworkUtils.getNetworkType()
            withContext(Dispatchers.Main) {
                mMiniDialog.dismiss()
                if (mType == NetworkUtils.NetworkType.NETWORK_NO) {
                    EteLog.d(LogManager.TAG, "网络不可用！")
                    ToastUtils.showShort(R.string.upload_not_network)
                } else if (ManagerConstant.NETWORK_CELLULARS.contains(mType)) {
                    EteLog.d(LogManager.TAG, "移动网络，流量使用过大提醒")
                    showNotWifiDialog()
                } else {
                    EteLog.d(LogManager.TAG, "WIFI网络，压缩APP目录")
                    val mFile: File? = getAppZipLogFile()
                    if (mFile != null) {
                        showHadLogDialog(mFile, isChooseDir)
                    } else {
                        showUploadLogDialog(isChooseDir)
                    }
                }
            }
            cancel()
        }
    }

    /**
     * 显示上报日志提示框
     *
     * @param isChooseDir 是否选择目录上传
     */
    @JvmStatic
    private fun showHadLogDialog(mZipFile: File, isChooseDir: Boolean) {
        val mContext = ActivityUtils.getTopActivity() ?: return
        val mDialogEntry = CommonDialogEntry(
                mContext = mContext,
                mTitle = mContext.getString(R.string.upload_upload_log),
                mContent = mContext.getString(R.string.upload_zip_log_exists),
                themeColor = mZipEntry.mAppThemeColor,
                mSureContent = mContext.getString(R.string.upload_upload),
                mCancelContent = mContext.getString(R.string.upload_zip_restart_create),
                mSureCallback = {
                    val mDialogDialog = getCommonDialog(
                            mTitle = R.string.upload_zip_upload_log,
                            mContent = R.string.upload_zip_uploading2,
                            isShowCancel = true,
                            isShowSure = false,
                            isOutTouchCancel = false,
                            isShowClose = false,
                            mCallback = {}
                    )
                    realUploadFile(mDialogDialog, mZipFile.path, mInputContent, false)
                    true
                },
                mCancelCallback = {
                    ServiceUtil.executeByIo(doInBackground = {
                        FileUtils.deleteFilesInDir(mZipNormalLogDir)
                    }, onSuccess = {
                        showUploadLogDialog(isChooseDir)
                    })
                    true
                }
        )
        val dialog = CommonDialog(mDialogEntry)
        dialog.initDialog()
        dialog.show()
    }

    /**
     * 显示上报日志提示框
     *
     * @param isChooseDir 是否选择目录上传
     */
    @JvmStatic
    private fun showUploadLogDialog(isChooseDir: Boolean) {
        if (isChooseDir) {
            showChooseDirDialog()
        } else {
            showInputDescriptionDialog()
        }
    }

    /**
     * 问题描述Dialog
     */
    @JvmStatic
    private fun showInputDescriptionDialog() {
        val mContext = ActivityUtils.getTopActivity() ?: return
        val mInputDialog = InputDescriptionDialog(mContext, mZipEntry.mAppThemeColor,
                mCallback = { startZipFileDir(mZipEntry.mAppDirs, it, false) })
        mInputDialog.initDialog(mInputContent)
        mInputDialog.show()
    }

    /**
     * 问题描述Dialog
     */
    @JvmStatic
    private fun showChooseDirDialog() {
        val mContext = ActivityUtils.getTopActivity() ?: return
        val mChooseDialog = ChooseUploadDirDialog(mContext, mZipEntry,
                mCallback = { dirs, input ->
                    startZipFileDir(dirs, input, false)
                }
        )
        mChooseDialog.initDialog(mInputContent)
        mChooseDialog.show()
    }

    /**
     * 正式上传日志
     */
    @JvmStatic
    private fun realUploadFile(
            mDialogDialog: CommonDialog?,
            mZipPath: String,
            mDescription: String,
            isSystemLog: Boolean
    ) {
        EteLog.d(LogManager.TAG, "正式上传日志压缩包mZipPath:[$mZipPath]，mDescription:[$mDescription]")
        val mUploadFile = File(mZipPath)
        val md5 = FileUtils.getFileMD5ToString(mUploadFile)
        val mAppType = mZipEntry.mAppType
        val deviceId = mZipEntry.deviceId
        val parameter: HashMap<String, RequestBody> = ParamHelper.getInstance()
            .addParameter("deviceId", deviceId)
            .addParameter("appType", mAppType)
            .addParameter("description", mDescription)
            .addParameter("md5", md5)
            .addParameter("uploadFile", mUploadFile)
            .builder()
        EteLog.d(
                LogManager.TAG,
                "上报日志文件参数deviceId:[$deviceId]，mAppType:[$mAppType]，description:[$mDescription]，md5:[$md5]"
        )
        val mCallback = object : Callback<BaseResponse<Boolean>> {
            override fun onResponse(
                    call: Call<BaseResponse<Boolean>>,
                    response: Response<BaseResponse<Boolean>>
            ) {
                cancelLogDelayJob()
                RetrofitClient.removeProgressInterceptor(mProgressKey)
                mDialogDialog?.dismiss()
                if (!response.isSuccessful) {
                    EteLog.d(LogManager.TAG, "上传日志，请求服务器错误: ${response.message()}")
                    ToastUtils.showShort("${getString(R.string.upload_log_result_request_server_error)}: ${response.message()}")
                    return
                }
                val result = response.body()
                if (result == null) {
                    EteLog.d(LogManager.TAG, "上传日志，服务器响应为空")
                    ToastUtils.showShort(R.string.upload_log_result_server_response_null)
                    return
                }
                val isSuccess = result.succ
                if (isSuccess == null || !isSuccess) {
                    EteLog.d(LogManager.TAG, ("上传日志，" + (result.msg ?: "请求服务器错误")))
                    ToastUtils.showShort(result.msg ?: getString(R.string.upload_log_result_request_server_error))
                    return
                }
                val isUploadSuccess = result.data
                if (isUploadSuccess == null || !isUploadSuccess) {
                    EteLog.d(LogManager.TAG, "日志上传失败")
                    ToastUtils.showShort(R.string.upload_log_result_fail)
                    return
                }
                EteLog.d(LogManager.TAG, "日志上传成功，删除压缩包mZipPath:[$mZipPath]")
                ServiceUtil.executeByIo(doInBackground = {
                    FileUtils.delete(mZipPath)
                    mInputContent = ""
                    if (isSystemLog) {
                        FileUtils.deleteFilesInDir(mZipSystemLogDir)
                    } else {
                        FileUtils.deleteFilesInDir(mZipNormalLogDir)
                    }
                })
                ToastUtils.showShort(R.string.upload_log_result_success)
                cancelLogTask()
            }

            override fun onFailure(call: Call<BaseResponse<Boolean>>, t: Throwable) {
                if (call.isCanceled) {
                    EteLog.d(LogManager.TAG, "上传Log任务已取消")
                } else {
                    RetrofitClient.removeProgressInterceptor(mProgressKey)
                    t.printStackTrace()
                    mDialogDialog?.dismiss()
                    val message = ExceptionTranslate.translateException(t).message
                    EteLog.d(LogManager.TAG, "日志上传错误message:[$message]")
                    ToastUtils.showShort(message)
                }
                cancelLogTask()
                cancelLogDelayJob()
            }
        }
        val mProgress = object : IProgressListener {
            override fun onStart(mProgressKey: String) {
                EteLog.d(LogManager.TAG, "开始上传日志")
                mUploadProgress = 0
                UploadLogUtil.mProgressKey = mProgressKey
                ThreadUtils.runOnUiThread {
                    val mTitle = Utils.getApp().getString(R.string.upload_zip_upload_log)
                    val mContent = Utils.getApp().getString(R.string.upload_zip_uploading, "0/100")
                    if (mDialogDialog?.isShowing == false) {
                        mDialogDialog.show()
                    }
                    mDialogDialog?.isShowCancelBtn(true)
                    mDialogDialog?.updateTouchCancel(false)
                    mDialogDialog?.updateCancelCallback(mCallback = {
                        cancelUploadLogDialog(callback = {
                            mDialogDialog.dismiss()
                        })
                        false
                    })
                    mDialogDialog?.updateTitle(mTitle)
                    mDialogDialog?.updateContent(mContent)
                }
            }

            override fun onProgress(progress: Int) {
                if (mUploadProgress != progress) {
                    mUploadProgress = progress
                    EteLog.d(LogManager.TAG, "上传日志进度progress:[$progress]")
                    ThreadUtils.runOnUiThread {
                        val mContent = Utils.getApp()
                            .getString(R.string.upload_zip_uploading, "${progress}/100")
                        mDialogDialog?.updateContent(mContent)
                    }
                }
            }

            override fun onFinish() {
                mUploadProgress = 0
                EteLog.d(LogManager.TAG, "日志写入完成")
//                actionDelayLogJob(mDialogDialog, mZipPath, isSystemLog)
            }
        }
        mUploadLogCall = RetrofitClient.createProgressService(ServiceApi::class.java, mProgress)
            .uploadLogFile(parameter)
        mUploadLogCall?.enqueue(mCallback)
    }

    private fun actionDelayLogJob(
            mDialogDialog: CommonDialog?, mZipPath: String, isSystemLog: Boolean
    ) {
        cancelLogDelayJob()
        mLogDelayJob = CoroutineScope(Dispatchers.IO).launch {
            delay(LOG_DELAY_TIME)
            withContext(Dispatchers.Main) {
                RetrofitClient.removeProgressInterceptor(mProgressKey)
                mDialogDialog?.dismiss()
                EteLog.d(LogManager.TAG, "日志上传成功，删除压缩包mZipPath:[$mZipPath]")
                ServiceUtil.executeByIo(doInBackground = {
                    FileUtils.delete(mZipPath)
                    if (isSystemLog) {
                        FileUtils.deleteFilesInDir(mZipSystemLogDir)
                    } else {
                        mInputContent = ""
                        FileUtils.deleteFilesInDir(mZipNormalLogDir)
                    }
                })
                ToastUtils.showShort(R.string.upload_log_result_success)
                cancelLogTask()
                cancelLogDelayJob()
            }
        }
    }

    private fun cancelLogDelayJob() {
        mLogDelayJob?.cancel()
        mLogDelayJob = null
    }

    @JvmStatic
    private fun cancelUploadLogDialog(callback: () -> Unit) {
        val mDialogDialog = getCommonDialog(
                mTitle = R.string.upload_upload_log,
                mContent = R.string.upload_cancel_upload,
                isShowLoading = false,
                mCallback = {
                    ToastUtils.showShort(R.string.upload_cancel_upload_success)
                    cancelLogTask()
                    cancelLogDelayJob()
                    callback.invoke()
                }
        )
        mDialogDialog?.show()
    }

    /**
     * 开始压缩App日志目录
     */
    @JvmStatic
    private fun startZipFileDir(
            dirs: MutableList<String>, mDescription: String = "", isSystemLog: Boolean,
    ) {
        if (mDescription.isEmpty()) {
            ToastUtils.showShort(R.string.upload_input_des_question)
            return
        }
        cancelLogTask()
        cancelLogDelayJob()
        isZipCancel = false
        mInputContent = mDescription
        val mZipFile: File? = if (isSystemLog) null else getAppZipLogFile()
        val isShowCancel = (mZipFile != null)
        val mTitle = if (mZipFile == null) {
            R.string.upload_zip_app_dir
        } else {
            R.string.upload_zip_upload_log
        }
        val mContent = if (mZipFile == null) {
            R.string.upload_zip_progress2
        } else {
            R.string.upload_zip_uploading2
        }
        val mDialogDialog = getCommonDialog(
                mTitle = mTitle,
                mContent = mContent,
                isShowCancel = isShowCancel,
                isShowSure = false,
                isOutTouchCancel = false,
                isShowClose = false,
                mCallback = {
                    startZipFileDir(dirs, mDescription, isSystemLog)
                }
        )
        if (mZipFile != null) {
            val mFilePath = mZipFile.path
            EteLog.d(LogManager.TAG, "本地存在App目录压缩文件mFilePath:[$mFilePath]")
            realUploadFile(mDialogDialog, mFilePath, mDescription, isSystemLog)
        } else {
            val toZipPath = if (isSystemLog) {
                mZipSystemLogDir + File.separator + System.currentTimeMillis() +
                        ".${ManagerConstant.ZIP_FILE_EXTENSION}"
            } else {
                FileUtils.createOrExistsDir(mZipNormalLogDir)
                mZipNormalLogDir + File.separator + System.currentTimeMillis() +
                        ".${ManagerConstant.ZIP_FILE_EXTENSION}"
            }
            EteLog.d(LogManager.TAG, "本地不存在App目录压缩文件，打包压缩文件toZipPath:[$toZipPath]")
            val mCallback = object : IZipCallback {
                override fun onStart() {
                    EteLog.d(LogManager.TAG, "开始打包App目录压缩文件")
                    val mContent2 = Utils.getApp().getString(R.string.upload_zip_progress, "0/100")
                    mDialogDialog?.updateContent(mContent2)
                    mDialogDialog?.show()
                }

                override fun onProgress(progress: Int) {
                    if (mZipProgress != progress) {
                        mZipProgress = progress
                        EteLog.d(LogManager.TAG, "打包App目录压缩文件进度progress:[$progress]")
                        val mContent2 = Utils.getApp()
                            .getString(R.string.upload_zip_progress, "${progress}/100")
                        mDialogDialog?.updateContent(mContent2)
                    }
                }

                override fun onError(code: Int, msg: String) {
                    mZipProgress = 0
                    EteLog.d(LogManager.TAG, "打包App目录压缩文件错误msg:[$msg]")
                    mDialogDialog?.dismiss()
                    ToastUtils.showShort(msg)
                }

                override fun onSuccess(scrPath: MutableList<String>, zipPath: String) {
                    mZipProgress = 0
                    EteLog.d(LogManager.TAG, "打包App目录压缩文件成功scrPath:[$scrPath]，zipPath:[$zipPath]")
                    val mContent2 = Utils.getApp().getString(R.string.upload_zip_success)
                    mDialogDialog?.updateContent(mContent2)
                    realUploadFile(mDialogDialog, zipPath, mDescription, isSystemLog)
                }
            }
            ZipFileUtil.zipDirFile(dirs, toZipPath, mCallback, mZipEntry.mZipPassword)
        }
    }

    /**
     * 非wifi提醒
     */
    @JvmStatic
    private fun showNotWifiDialog() {
        val mDialogDialog = getCommonDialog(
                mTitle = R.string.upload_network_tip,
                mContent = R.string.upload_network_content,
                isShowLoading = false,
                mCallback = { showInputDescriptionDialog() }
        )
        mDialogDialog?.show()
    }

    @JvmStatic
    private fun getCommonDialog(
            mTitle: Int, mContent: Int,
            isShowSure: Boolean = true,
            isShowCancel: Boolean = true,
            isOutTouchCancel: Boolean = true,
            isShowClose: Boolean = true,
            isShowLoading: Boolean = true,
            mCallback: () -> Unit
    ): CommonDialog? {
        val mContext: Context = ActivityUtils.getTopActivity() ?: return null
        val mDialogEntry = CommonDialogEntry(
                mContext = mContext,
                mTitle = mContext.getString(mTitle),
                mContent = mContext.getString(mContent),
                themeColor = mZipEntry.mAppThemeColor,
                isOutTouchCancel = isOutTouchCancel,
                isShowLoading = isShowLoading,
                isShowSure = isShowSure,
                isShowCancel = isShowCancel,
                isShowClose = isShowClose,
                mSureCallback = {
                    mCallback.invoke()
                    true
                }
        )
        val dialog = CommonDialog(mDialogEntry)
        dialog.initDialog()
        return dialog
    }

    /**
     * 正式上传日志
     */
    @JvmStatic
    fun uploadFileInBackground(
            filePath: String,
            mDescription: String,
            callback: ((Boolean) -> Unit)?
    ) {
        EteLog.d(LogManager.TAG, "后台上报日志, 文件:[$filePath]，描述:[$mDescription]")
        val mUploadFile = File(filePath)
        val deviceId = mZipEntry.deviceId
        val md5 = FileUtils.getFileMD5ToString(mUploadFile)
        val mAppType = mZipEntry.mAppType
        val parameter: HashMap<String, RequestBody> = ParamHelper.getInstance()
            .addParameter("deviceId", deviceId)
            .addParameter("appType", mAppType)
            .addParameter("description", mDescription)
            .addParameter("md5", md5)
            .addParameter("uploadFile", mUploadFile)
            .builder()
        EteLog.d(
                LogManager.TAG,
                "上报日志文件参数deviceId:[$deviceId]，mAppType:[$mAppType]，description:[$mDescription]，md5:[$md5]"
        )
        val mCallback = object : Callback<BaseResponse<Boolean>> {
            override fun onResponse(
                    call: Call<BaseResponse<Boolean>>,
                    response: Response<BaseResponse<Boolean>>
            ) {
                if (!response.isSuccessful) {
                    EteLog.d(LogManager.TAG, "上传日志，请求服务器错误: ${response.message()}")
                    ToastUtils.showShort("${getString(R.string.upload_log_result_request_server_error)}: ${response.message()}")
                    callback?.invoke(false)
                    return
                }
                val result = response.body()
                if (result == null) {
                    EteLog.d(LogManager.TAG, "上传日志，服务器响应为空")
                    callback?.invoke(false)
                    return
                }
                val isSuccess = result.succ
                if (isSuccess == null || !isSuccess) {
                    EteLog.d(LogManager.TAG, ("上传日志，" + (result.msg ?: "请求服务器错误")))
                    callback?.invoke(false)
                    return
                }
                val isUploadSuccess = result.data
                if (isUploadSuccess == null || !isUploadSuccess) {
                    EteLog.d(LogManager.TAG, "日志上传失败")
                    callback?.invoke(false)
                    return
                }
                EteLog.d(LogManager.TAG, "日志上传成功，删除文件:[$filePath]")
                callback?.invoke(true)
                ServiceUtil.executeByIo(doInBackground = {
                    FileUtils.delete(filePath)
                    FileUtils.deleteFilesInDir(mZipNormalLogDir)
                })
                cancelLogTask()
            }

            override fun onFailure(call: Call<BaseResponse<Boolean>>, t: Throwable) {
                if (call.isCanceled) {
                    EteLog.d(LogManager.TAG, "上传Log任务已取消")
                } else {
                    t.printStackTrace()
                    val message = ExceptionTranslate.translateException(t).message
                    EteLog.d(LogManager.TAG, "日志上传错误message:[$message]")
                }
                callback?.invoke(false)
            }
        }
        val mProgress = object : IProgressListener {
            override fun onStart(mProgressKey: String) {
                EteLog.d(LogManager.TAG, "开始上传日志")
            }

            override fun onProgress(progress: Int) {
                Log.d(LogManager.TAG, "上传日志进度progress:[$progress]")
            }

            override fun onFinish() {
                EteLog.d(LogManager.TAG, "日志写入完成")
            }
        }
        val mUploadLogCall = RetrofitClient.createProgressService(ServiceApi::class.java, mProgress)
            .uploadLogFile(parameter)
        mUploadLogCall.enqueue(mCallback)
    }

    /**
     * 上传系统日志
     */
    @JvmStatic
    fun uploadSystemLog() {
        isNetworkAvailable(mCallback = { uploadSystemDialog() })
    }

    /**
     * 上报系统日志确定
     */
    private fun uploadSystemDialog() {
        val mDialogDialog = getCommonDialog(
                mTitle = R.string.upload_system_log,
                mContent = R.string.upload_system_log_content_tip,
                isShowCancel = true,
                isShowSure = true,
                isShowLoading = false,
                isShowClose = true,
                mCallback = {
                    writerSystemLogToLocal()
                }
        )
        mDialogDialog?.show()
    }

    /**
     * 把系统日志写入本地目录
     */
    private fun writerSystemLogToLocal() {
        val mDialogDialog = getCommonDialog(
                mTitle = R.string.upload_system_log,
                mContent = R.string.upload_system_log_content,
                isShowCancel = false,
                isShowSure = false,
                isOutTouchCancel = false,
                isShowClose = false,
                mCallback = {}
        )
        mDialogDialog?.show()
        CoroutineScope(Dispatchers.IO).launch {
            val isSuccess = SystemLogUtil.createSystemLog(mZipSystemLogDir)
            withContext(Dispatchers.Main) {
                mDialogDialog?.dismiss()
                if (isSuccess) {
                    startZipFileDir(listOf(mZipSystemLogDir).toMutableList(), "系统日志", true)
                } else {
                    ToastUtils.showShort(R.string.upload_get_system_log_fail)
                }
            }
            cancel()
        }
    }

    /**
     * 网络是否可用
     */
    @JvmStatic
    private fun isNetworkAvailable(mCallback: () -> Unit) {
        val mContext = ActivityUtils.getTopActivity()
        if (mContext == null) {
            mCallback.invoke()
            return
        }
        val mMiniDialog = MiniLoadingDialog.getMiniDialog(mContext, R.string.upload_check_network)
        mMiniDialog.show()
        CoroutineScope(Dispatchers.IO).launch {
            FileUtils.deleteFilesInDir(mZipSystemLogDir)
            val isAvailable = NetworkUtils.isAvailable()
            withContext(Dispatchers.Main) {
                mMiniDialog.dismiss()
                if (!isAvailable) {
                    EteLog.d(LogManager.TAG, "网络不可用！")
                    ToastUtils.showShort(R.string.upload_not_network)
                } else {
                    EteLog.d(LogManager.TAG, "WIFI网络，压缩APP目录")
                    mCallback.invoke()
                }
            }
            cancel()
        }
    }
}